package com.yunxin.common.utils.oss;

import com.aliyun.oss.event.ProgressEvent;
import com.aliyun.oss.event.ProgressEventType;
import com.aliyun.oss.event.ProgressListener;
import lombok.extern.slf4j.Slf4j;

/**
 * 获取(下载)OSS对象进度监听器
 * @author zero°
 * @since 2023-06-05
 */
@Slf4j
public class GetObjectProgressListener implements ProgressListener {

    /**
     * 已读字节数
     */
    private long bytesRead = 0;

    /**
     * 总字节数
     */
    private long totalBytes = -1;

    /**
     * 是否成功
     */
    private boolean succeed = false;

    /**
     * 桶名称
     */
    private final String bucketName;

    /**
     * OSS文件路径
     */
    private final String ossFilePath;

    public GetObjectProgressListener(String bucketName, String ossFilePath) {
        this.bucketName = bucketName;
        this.ossFilePath = ossFilePath;
    }

    @Override
    public void progressChanged(ProgressEvent progressEvent) {
        long bytes = progressEvent.getBytes();
        ProgressEventType eventType = progressEvent.getEventType();
        switch (eventType) {
            case TRANSFER_STARTED_EVENT:
                log.info("桶:{},文件:{},开始下载......", bucketName, ossFilePath);
                break;
            case RESPONSE_CONTENT_LENGTH_EVENT:
                this.totalBytes = bytes;
                log.info("桶:{},文件:{},准备下载,总字节数:{}......", bucketName, ossFilePath, this.totalBytes);
                break;
            case RESPONSE_BYTE_TRANSFER_EVENT:
                this.bytesRead += bytes;
                if (this.totalBytes != -1) {
                    int percent = (int) (this.bytesRead * 100.0 / this.totalBytes);
                    log.info("桶:{},文件:{},下载中,总字节数:{},已下载字节数:{} => {}/{}({}%)......", bucketName, ossFilePath,
                            this.totalBytes, this.bytesRead, this.bytesRead, this.totalBytes, percent);
                } else {
                    log.info("桶:{},文件:{},下载中,已下载字节数:{},下载进度未知......", bucketName, ossFilePath, this.bytesRead);
                }
                break;
            case TRANSFER_COMPLETED_EVENT:
                this.succeed = true;
                log.info("桶:{},文件:{},下载完成(成功)......", bucketName, ossFilePath);
                break;
            case TRANSFER_FAILED_EVENT:
                log.warn("桶:{},文件:{},下载失败......", bucketName, ossFilePath);
                break;
            default:
                break;
        }
    }

    public boolean isSucceed() {
        return succeed;
    }

}
